    ;^Z80^
    TITLE FILE: DDP_MANAG:TOS      HEWLETT-PACKARD: DDP_MANAGER  (c) Coleco 1983 Confidential
    ;NAME ^Rev 01 - DTT^

    De_DDP_MANAGER MACRO              ;Header Rev. 5
                    .GOTO Ede_DDP_MANAGER

     Project:       H132, VS

     ******************************
     *                            *
     *  DDP_MANAGER           DTT   *
     *                            *
     ******************************

           Rev History
           Rev.  Date         Name      Change
            1             DTT       DEVICE_ID --> DEV_ID
            0    9/9/83   DTT       Initial Pseudo Code

     Function:

          CONTROLS THE DIGITAL DATA PACK FOR READS AND WRITES SETUP BY TAPE_INTERFACE

    Ede_DDP_MANAGER  MEND
    Pseudo_code_DDP_MANAGER    MACRO  ;Pseudocode macro area
                       .GOTO Ep_DDP_MANAGER

    Ep_DDP_MANAGER  MEND

    ;Inputs/Outputs passed in registers
    ;  CALLED EVERY 60th SECOND BY THE NMI

    TAPE1          EQU  08H
    READ_TAPE      EQU  81H
    WRITE_TAPE     EQU  82H
    KILL_TAPE      EQU  87H
     INCLUDE P_DCB_EQ.ASM                  ;INCLUDE P_DCB_EQU:EOS
     INCLUDE EOS_ERRS.ASM                  ;INCLUDE EOS_ERRS:EOS

    ;*EXTERNAL DATA AREAS USED:

                    EXT _START_RD_1_BLOCK
                    EXT _FIND_DCB
                    EXT _START_WR_1_BLOCK
                    EXT _END_RD_1_BLOCK

    NEXT_STATE      MACRO LP1
             LD     A,LP1                          ;SOMETHING IN THE COMMAND BUFFER!
             LD     [D_TAPE_STATE],A
             LD     HL,[STATE_VECTORS+LP1+LP1]
             LD     [NEXT_STATE_ADDRESS],HL
             JP     END_OF_STATE_MACHINE
             MEND

           GLOBAL  DEV_ID
           GLOBAL  INITIALIZE_DDP,INITIALIZE_TAPE,INIT_TAPE,INIT_DDP
    INITIALIZE_DDP:
    INITIALIZE_TAPE:
    INIT_TAPE:
    INIT_DDP:
    INIT_CODE:
             XOR    A
             LD     (D_CSA),A
             LD     (D_TAPE_STATE),A
             DEC    A
             LD     (D_OVERLAY_NUMBER),A
             LD     HL,(STATE_VECTORS+0000)          ;IDLE STATE
             LD     (NEXT_STATE_ADDRESS),HL
             RET
    STATE_VECTORS:
             DEFW   STATE_IDLE                       ;STATE 0
             DEFW   STATE_1                          ;      1  REQUEST FOR I/O FOR 1 BLOCK
             DEFW   STATE_2                          ;      2  TEST FOR COMPLETE AND REQUEST STATUS
             DEFW   STATE_3                          ;      3  TEST STATUS
    LEN_INIT EQU $-INIT_CODE
    ;*
    ;*

             DEFS   1BH-LEN_INIT    ;MAKE SURE THE MANAGER VECTOR IS AT THE SAME LOC AS THE S/IO_MANAGER

           GLOBAL  DDP_MANAGER
           GLOBAL  TAPE_MANAGER
    TAPE_MANAGER:
    DDP_MANAGER:
    ;*  BEGIN        (Ordinarily registers are restored; retain only the pushes and pops you need.)
    ;*
    ;*
    ;*
    ;*                FALL THRU TO CASE STATEMENT     ;IF STATE = 6,7
    ;*                                                ;FILE IS TRYING TO CLOSE
    ;*
    ;*
    ;*        CASE    D_TAPE_STATE,(IDLE,STATE_1,STATE_2,STATE_3,INIT_DDP)
    ;*
    CASE_STATE:
    ;*
    ;*
             LD     HL,[NEXT_STATE_ADDRESS]
             JP     [HL]
    ;*
    ;*        IF THE MACHINE IS IDLE IT'S OK TO TEST FOR ANOTHER I/O REQUEST
    ;*
    STATE_IDLE:                                     ;STATE 0
             LD     A,[D_CSA]                 ;TEST THE COMMAND STATUS AREA
             OR     A
             JP     P,END_OF_STATE_MACHINE    ;IF THE CSA CONTAINS AN ERROR CODE DON't PROCESS IT
    ;*
    ;*               FALL THROUGH TO STATE 1
    ;*
    STATE_1:
    AB_REQ:  LD     A,(D_CSA)                          ;IF COMMAND IS TO KILL DDP COMMAND
             CP     KILL_TAPE
             JP     Z,INIT_DDP
    ;*
    ;*        REQUEST TO WRITE/READ A RECORD
    ;*

             LD     HL,(XFER_ADDR)
             LD     DE,(BLOCK_NUM)
             LD     BC,0000H
             LD     A,(D_CSA)
             CP     READ_TAPE
             LD     A,(DEV_ID)
             JR     NZ,EOS_TAPE_WRITE
    EOS_TAPE_READ:
             CALL   _START_RD_1_BLOCK
             JR     RET_ADDR
    EOS_TAPE_WRITE:
             CALL   _START_WR_1_BLOCK

    RET_ADDR:
             NEXT_STATE 2

    ;*
    ;*               TEST FOR ACCEPTANCE/COMPLETION OF I/O REQUEST
    ;*
    STATE_2:
             LD     A,(DEV_ID)              ;TEST THE STATUS OF THE FILE
             CALL   _END_RD_1_BLOCK
             JP     NC,END_OF_STATE_MACHINE           ;BETTER RETRY STATE 2
    ;*
    ;*        AT THIS POINT THE COMMAND HAS BEEN ACCEPTED BY THE NETWORK
    ;*        IF THE ZERO FLAG IS NOT SET THERE HAVE BEEN ERRORS (09BH=TIMEOUT)
    ;*

             JR     NZ,STATE_1                         ;BETTER RETRY STATE 1
    ;*
    ;*        IF NO ERRORS THEN SET UP REQUEST STATUS OF THE TAPE DRIVE
    ;*        THIS TESTS THE CHECK SUM (CRC) OF THE DATA XMITTED BY THE TAPE
    ;*
    STATE_2_OK:
    ;*
             LD   A,(DEV_ID)                          ;STATUS COMMAND
             CALL _FIND_DCB
             LD   (IY+D_COM_STAT),DCB_STATUS
             NEXT_STATE 3
    ;*
    ;*        IN STATE 3 TEST FOR ACCEPTANCE OF THE REQUEST FOR STATUS COMMAND
    ;*
    STATE_3:
             LD   A,(DEV_ID)
             CALL _FIND_DCB                            ;WAS THE STATUS REQUEST ACKNOWLEDGED????
             BIT  CMND_COMPLETE_BIT,(IY+D_COM_STAT)
             JP   Z,END_OF_STATE_MACHINE
    ;*
    ;*        IF THE COMMAND IS NOT YET ACCEPTED, COME BACK TO STATE 3 NEXT PASS
    ;*
             LD   A,(IY+D_COM_STAT)                   ;STATUS COMMAND ACCEPTED
             CP   080H
             JR   NZ,STATE_2_OK                        ;COULD NOT GET STATUS?
    ;*
    ;*
    ;*
                                                       ;SAVE THE STATUS IN REGISTER B
             LD   A,(DEV_ID)                        ;CHECK FOR SECONDARY DEVICE ID
             AND  0F0H
             LD   A,(IY+D_STATUS_FLAGS)
             JR   Z,DEV_0_CHECK                        ;SECONDARY_DEV_ID=0
             RR   A                                    ;GET STATUS INTO THE LOW NIBBLE
             RR   A
             RR   A
             RR   A
    DEV_0_CHECK:
             AND  0FH
             JP   NZ,ERROR                             ;A BAD STATUS
    ;*
    ;*        IF THE COMMAND IS ACCEPTED AND THERE ARE NO ERRORS INCREMENT THE CSA DATA
    ;*
             LD   HL,(XFER_ADDR)                        ; A BLOCK HAS BEEN WRITTEN OR READ
             LD   DE,(BLOCK_NUM)                        ;UPDATE THE D_CSA AREA!
             LD   BC,0400H
             LD   A,(RANGE)
             DEC  A
             JP   Z,INIT_DDP                           ;DONE WITH OVERLAY?
    ;*
    ;*        IF THE RANGE WAS DECREMENTED TO ZERO WE ARE DONE ELSE (WE ARE NOT?)
    ;*
             LD   (RANGE),A
             INC  DE
             LD   (BLOCK_NUM),DE
             ADD  HL,BC
             LD   (XFER_ADDR),HL

             JP   STATE_1

    ;*
    ;*               ERROR PROCESSING FROM REQUEST STATUS
    ;*
    ERROR:
    ;*               Errors occur after request status
    ;*               Possible errors are 1=CRC error (bad data on tape)
    ;*               2=block not found   3=no tape in drive  4=no drive
    ;*               The user program is expected to test for errors via
    ;*               TEST_TAPE in the TAPE_INTERFACE module.
    ;*
    ;*
              LD   (D_CSA),A                        ;SAVE THE ERROR CODE IN THE CSA
              LD   HL,(STATE_VECTORS+0)             ;NEXT STATE = IDLE
              LD   (NEXT_STATE_ADDRESS),HL

    ;*  END (DDP_MANAGER)

    END_OF_STATE_MACHINE:
           XOR A
           RET
    ;************************************************************************
    ;*****           DEV_ID IS DEFAULT 08 FOR TAPE DRIVE 0           *****
    ;************************************************************************

    DEV_ID      DEFB TAPE1

    ;************************************************************************
    ;************************************************************************
    ;************************************************************************
           GLOBAL D_OVERLAY_NUMBER
           GLOBAL D_TAPE_STATE
           GLOBAL D_CSA
    ;*--------------------------------------------------------------
    ;*THE NEXT_STATE_ADDRESS MAY BE PUT IN DATA,PROG,OR COMN (IT'S ALL RAM TO ADAM)
    ;*
    NEXT_STATE_ADDRESS DEFS 2
    ;*--------------------------------------------------------------
    ;*               BY MAKING THE CSA COMMON IT IS EASILY LINKED
    ;*               INTO EXISTING CODE
     DATA
    D_OVERLAY_NUMBER DEFS 1
    D_TAPE_STATE     DEFS 1
    D_CSA            DEFS 6
    XFER_ADDR EQU D_CSA+1
    BLOCK_NUM EQU XFER_ADDR+2
    RANGE     EQU BLOCK_NUM+2